package cn.edu.scnu.swagger.interceptor;

import cn.edu.scnu.annotation.IgnoreToken;
import cn.edu.scnu.annotation.NeedAdmin;
import cn.edu.scnu.exception.NoAuthority;
import cn.edu.scnu.exception.NoLoginException;
import cn.edu.scnu.pojo.User;
import cn.edu.scnu.utils.MapperUtil;
import cn.edu.scnu.utils.RestTemplateUtils;
import cn.edu.scnu.vo.SysResult;
import cn.edu.scnu.vo.UserTypes;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Resource(type = RestTemplate.class)
    private RestTemplate restTemplate;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        // 如果不是映射到方法直接通过
        if (!(o instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) o;
        Method method = handlerMethod.getMethod();

        //检查方法是否有IgnoreToken注解，有则跳过认证，直接通过
        if (method.isAnnotationPresent(IgnoreToken.class)) {
            return true;
        }

        SysResult result = RestTemplateUtils.exchangeWithToken(restTemplate, httpServletRequest,
                "http://userService/users/queryticket", HttpMethod.GET);
        String userJson = "";
        if (result.getStatus() == 200) {
            userJson = result.getData().toString();
            if (StringUtils.isNotEmpty(userJson)) {
                User user = MapperUtil.MP.readValue(result.getData().toString(), User.class);
                // 管理员权限
                if (method.isAnnotationPresent(NeedAdmin.class) && user.getType() != UserTypes.ADMIN.type) {
                    throw new NoAuthority("没有权限");
                }

                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user, null);
                authentication.setDetails(httpServletRequest);
                SecurityContextHolder.getContext().setAuthentication(authentication);
                return true;
            }
        }
        throw new NoLoginException("未登录");

//        String ticket = httpServletRequest.getHeader("token");
//        if (StringUtils.isEmpty(ticket)) {
//            throw new NoLoginException("未登录");
//        }
//        HttpHeaders headers = new HttpHeaders();
//        headers.set("token", ticket);
//        HttpEntity httpEntity = new HttpEntity(null, headers);
//        ResponseEntity<SysResult> exchange = restTemplate.exchange("http://userService/users/queryticket", HttpMethod.GET, httpEntity, SysResult.class);
//        SysResult result = null;
//        if (exchange.getStatusCode() == HttpStatus.OK) {
//            result = exchange.getBody();
//            String userJson = "";
//            if (result.getStatus() == 200) {
//                userJson = result.getData().toString();
//                if (StringUtils.isNotEmpty(userJson)) {
//                    User user = MapperUtil.MP.readValue(result.getData().toString(), User.class);
//                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user, null);
//                    authentication.setDetails(httpServletRequest);
//                    SecurityContextHolder.getContext().setAuthentication(authentication);
//                    return true;
//                }
//            }
//            throw new NoLoginException("未登录");
//        }
//        throw new Exception("服务器内部错误");
    }


    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}
